﻿using Konveyer.Core.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Konveyer.Core
{
    public abstract class ValidationWidget<T> : TypedWidget<T>
         where T : class,IRequest
    {
        private readonly List<Func<T, string>> _busnessRules = new List<Func<T, string>>();

        /// <summary>
        /// Add a method or business rules that will return an error message if the 
        /// request fails the test, return and empty string to indicate the request is valid
        /// </summary>
        /// <param name="businessRule"></param>
        protected void AddRule(Func<T, string> businessRule)
        { 
            _busnessRules.Add(businessRule);
        }

        protected override void Do(T request)
        {
            if (request == null)
            {
                throw new InvalidOperationException("Cannot process a null request");
            }

            var errors = new List<string>() ;

            _busnessRules.ForEach(x=> errors.Add(x(request)));

            errors.RemoveAll(String.IsNullOrWhiteSpace);
            if(errors.Any())
            {
                OnErrorsFound(request,errors);
            }
        }

        /// <summary>
        /// Override this to handle the error messages yourself.
        /// By default they are packaged into a WidgetVaildation Exception
        /// </summary>
        /// <param name="request"></param>
        /// <param name="errors"></param>
        protected virtual void OnErrorsFound(IRequest request, IEnumerable<string> errors)
        {
            if (errors.Any() && request != null)
            {
                request.Exception = new WidgetValidationException { ErrorMessages = errors };
            }
        }
    }
}
